package com.yz.pay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yz.model.dto.pay.AlipayNotifyDto;
import com.yz.model.dto.order.PayOrderRequest;
import com.yz.model.vo.pay.PayVo;
import com.yz.pay.constant.PayConstant;
import com.yz.pay.mapper.PayMapper;
import com.yz.pay.mq.*;
import com.yz.model.entity.pay.PayFlow;
import com.yz.pay.service.PayService;
import com.yz.pay.properties.AliPayProperties;
import com.yz.pay.utils.AlipayUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created With IntelliJ IDEA.
 * Descriptions:支付ServiceImpl
 * <p>
 * User:Mr.Du
 * Date:2024/3/27
 * Time:16:54
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PayServiceImpl extends ServiceImpl<PayMapper, PayFlow> implements PayService {

    private final AliPayProperties aliPayProperties;

    private final PayMessageProducer payMessageProducer;

    private final UserMessageProducer userMessageProducer;

    private final PromotionMessageProducer promotionMessageProducer;

    private final OrderMessageProducer orderMessageProducer;

    private final AlipayUtils alipayUtils;

    @Override
    public String reCharge(Long uid, PayOrderRequest payOrderRequest) {
        try{
            log.info("payOrderRequest支付信息:{}", payOrderRequest);
            //保存流水
            payMessageProducer.sendMessage(JSON.toJSONString(payOrderRequest));
            // 交易
            String path = sendPayment(payOrderRequest);
            return path;
        }catch (Exception e){
            log.info("支付异常", e);
            throw new RuntimeException("系统出错");
        }
    }

    @Override
    public String notifyUrl(AlipayNotifyDto alipayNotifyDto) {
        log.info("setTradeStatus: {}", alipayNotifyDto.getTrade_status());
        log.info("回调了");
        String payStatus = "fail";
        boolean signVerified = false;
        Map<String, String> mp = JSON.parseObject(JSON.toJSONString(alipayNotifyDto), Map.class);
        try {
            signVerified = AlipaySignature.rsaCheckV1(mp, aliPayProperties.getPublicKey(), aliPayProperties.getCharset(), aliPayProperties.getSignType());
            log.info("【异步通知签名验证】" + signVerified);
        }catch (AlipayApiException e){
            System.out.println("【异步签名异常】" + e.getErrMsg());
            return payStatus;
        }
        if(signVerified && "TRADE_SUCCESS".equals(alipayNotifyDto.getTrade_status())){
            log.info("【TRADE_SUCCESS】" + "TRADE_SUCCESS");
            // 更新流水
            updatePayFlowSuccess(alipayNotifyDto.getOut_trade_no());
            // 更新订单
            orderMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());
            // 消费优惠卷
            promotionMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());
            // 用户金币新增
            userMessageProducer.sendMessage(alipayNotifyDto.getOut_trade_no());
            payStatus = "success";
        }
        log.info("【异步通知签名验证】" + payStatus);
        return payStatus;
    }

    @Override
    public void returnUrl(HttpServletRequest request) throws UnsupportedEncodingException {

    }

    @Override
    public List<PayVo> getPayVoList() {
        log.info("getPayVoList start =================");
        List<PayFlow> payFlowList = this.list();
        log.info("payFlowList = {}", payFlowList);
        List<PayVo> payVoList = payFlowList.stream()
                .map(payFlow -> {
                    PayVo payVo = new PayVo();
                    BeanUtils.copyProperties(payFlow, payVo);
                    return payVo;
                })
                .collect(Collectors.toList());
        return payVoList;
    }

    private void updatePayFlowSuccess(String outTradeNo){
        QueryWrapper<PayFlow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("out_trade_no", Long.parseLong(outTradeNo));
        PayFlow payFlow = PayFlow.builder().build();
        payFlow.setTradeStatus(PayConstant.TRADE_SUCCESS);
        payFlow.setPaySuccess(true);
        boolean update = this.update(payFlow, queryWrapper);
        if(!update){
            log.info("更新流水失败");
            throw new RuntimeException("更新流水失败");
        }
    }

    private String sendPayment(PayOrderRequest payOrderRequest){
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayUtils.getAlipayConfig());
            AlipayTradePagePayRequest request = this.getAlipayTradePagePayRequest(payOrderRequest);
            request.setReturnUrl(aliPayProperties.getReturnUrl());
            request.setNotifyUrl(aliPayProperties.getNotifyUrl());
            // 调用SDK生成表单
            AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(request, "GET");
            String body = alipayTradePagePayResponse.getBody();
            return body;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private AlipayTradePagePayRequest getAlipayTradePagePayRequest(PayOrderRequest payOrderRequest) {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        //异步接收地址，仅支持http/https，公网可访问
        request.setNotifyUrl("");
        //同步跳转地址，仅支持http/https
        request.setReturnUrl("");
        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", payOrderRequest.getId());
        //支付金额，最小值0.01元
        bizContent.put("total_amount", payOrderRequest.getRealAmount());
        //订单标题，不可使用特殊符号
        bizContent.put("subject", payOrderRequest.getSubject());
        //电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        bizContent.put("timeout_express", aliPayProperties.getExpireTime());
        log.info("bizContent = {}", bizContent.toString());
        request.setBizContent(bizContent.toString());
        return request;
    }



}
